//Библиотека Qt.
#include <QApplication>
#include <QTimer>


//Внутренняя библиотека.
#include "threadblocker.h"


//===========================================================================//
//=Заголовок: ThreadBlocker::ThreadBlocker() - public
//=Параметры:
//=Описание: Конструктор.
//===========================================================================//
ThreadBlocker::ThreadBlocker(QObject *parent) : QObject(parent) {}


//===========================================================================//
//=Заголовок: void ThreadBlocker::addObject() - public
//=Параметры:
//=Описание: Функция добавления объекта в хэш.
//===========================================================================//
void ThreadBlocker::addObject(int index, QObject *obj)
{
connect(obj, SIGNAL(taskCompleted(int)), this, SLOT(slotTaskCompleted(int)), Qt::QueuedConnection);
objectsHash.insert(index, obj);
}


//===========================================================================//
//=Заголовок: bool ThreadBlocker::block() - public
//=Параметры:
//=Описание: Функция блокировки нити.
//===========================================================================//
bool ThreadBlocker::block(int timeout)
{
if(objectsHash.isEmpty()) return false;

if(timeout > 0)
	QTimer::singleShot(timeout, this, SLOT(slotBlockTimeout()));

isCompleted = false;
isRunning = true;
while(isRunning) {qApp->processEvents();}

return isCompleted;
}


//===========================================================================//
//=Заголовок: void ThreadBlocker::slotTaskCompleted() - private slots
//=Параметры:
//=Описание: Слот завершения задачи.
//===========================================================================//
void ThreadBlocker::slotTaskCompleted(int index)
{
if(!objectsHash.contains(index)) return;
QObject *obj = objectsHash.take(index);
disconnect(obj, SIGNAL(taskCompleted(int)), this, SLOT(slotTaskCompleted(int)));
if(objectsHash.isEmpty()) {isCompleted = true; isRunning = false;}
}


//===========================================================================//
//=Заголовок: void ThreadBlocker::slotBlockTimeout() - private slots
//=Параметры:
//=Описание: Слот окончания времени, отведённого на выполнение блокировки.
//===========================================================================//
void ThreadBlocker::slotBlockTimeout()
{isCompleted = false; isRunning = false; objectsHash.clear();}
